# 
#    Author : Inigo Gonzalez Vazquez <ingonza85 __at__ gmail __dot__ com>
#

from xml.dom import minidom
from xml.dom.minidom import Document
from django.http import HttpResponse
from django.template import Context, loader
from django.shortcuts import render_to_response
from format.utils import  generateResponse
import subprocess
import os
from os import path
import copy

#This function will generate the xml to use with openadaptor, and call to openadaptor for using that xml to get our own xml with the external data
def generate_XML(channel,category, posData):
    #Here we will parse the file with the channel information
    direccion = getPath()
    channel = channel.lower()
    category = category.lower()
    way = str(direccion) + "/channelsConfig/%s.xml" % (channel)
    xmldoc = minidom.parse(way)
    path = str(direccion) + "/agregator_files/temp/" + channel + "_" + category + ".xml"
    reflist = xmldoc.getElementsByTagName("category")
    i = 0
    pos = 0
    encontrado = False
    while (i < len(reflist)):
        idNode = reflist[i].firstChild
        if (idNode.firstChild.nodeValue == category):
            urlNode = reflist[i].childNodes[1]
            url = urlNode.firstChild.nodeValue
            typeNode = reflist[i].childNodes[2]
            type = str(typeNode.firstChild.nodeValue)
            pos = i #stores the position of the category
            i = len(reflist) + 1
            encontrado = True
        else:
            i = i + 1    
    if (encontrado == True):
        params = copy.deepcopy(posData)
        dependency = reflist[pos].getElementsByTagName("depends")
        if (len(dependency) > 0):
            j = 0
            #If there is needed a petition to other channel or category (dependency) we make it recursively
            while (j < len(dependency)): 
                #we get the channel
                channelNode = dependency[j].firstChild
                tempChannel = channelNode.firstChild.nodeValue
                #we get the category
                catNode = dependency[j].childNodes[1]
                tempCategory = catNode.firstChild.nodeValue
                depNode = dependency[j].childNodes[2]
                attList = depNode.getElementsByTagName("parameter")
                f = 0
                #Here we will obtain an openadaptor xml and all the parameters that the recursive calling has generated
                xmlFilePath, response2,params2 = generate_XML(tempChannel, tempCategory, params)
                params = copy.deepcopy(params2)                
                #Here we will call to openadaptor to use xmlFilePath to get more parameters (which are in atos) that we will add them to the params variable 
                document = minidom.parse(xmlFilePath)
                while(f < len(attList)):
                    ato = copy.deepcopy(str(attList[f].firstChild.nodeValue))
                    atribute = document.getElementsByTagName(ato)
                    params[ato] = atribute[0].firstChild.nodeValue
                    f = f + 1         
                document.unlink()               
                os.remove(xmlFilePath)
                j = j + 1
        lURL = url.split('#')
        tempURL = lURL[0]
        searchURL = generate_URL(tempURL, lURL, params)  
        if (searchURL[0] == "e"):
            xml = None
            list = searchURL.split(" ")
            response = "error " + list[1]
            params = None
            return xml, response, params        
        xml = str(direccion) + "/agregator_files/xmlConf/" + channel + "_" + category + ".xml"    
        xsl = str(direccion) + "/agregator_files/xslConf/" + channel + "_" + category + ".xsl" 
        data = {'url' : str(searchURL), 'xsl' : str(xsl), 'xml' : str(xml)}
        c = Context(data)
        template = "agregator/%sChannelTemplate.xml" % (type)
        t = loader.get_template(template)
        #mem is the xml fil for openadaptor
        mem = t.render(c)
        #response will be the return for the urlRequest and it is a HttpResponse and it contains the openadaptor xml
        respTemp = "agregator/%sChannelTemplate" % (type)
        path = str(direccion) + "/agregator_files/temp/" + channel + "_" + category + ".xml"
        fich = open(path,'w')
        fich.write(mem)
        fich.close()
        auxPath = str(direccion) + "/agregator_files/temp/"
        openAdaptorFile = 'file:' + path
        
        outfd = open(auxPath + 'archivo_out', 'w')
        errfd = open(auxPath + 'archivo_err', 'w')
        #This variable indicates where are openadaptor libraries
        if (os.path.isfile(str(xml))):
            os.remove(str(xml))  
        classPath = "/usr/local/openadaptor-3.4.4/lib:" + "/usr/local/openadaptor-3.4.4/lib/patch.jar:" "/usr/local/openadaptor-3.4.4/lib/openadaptor.jar:" + "/usr/local/openadaptor-3.4.4/lib/openadaptor-spring.jar:" + "/usr/local/openadaptor-3.4.4/lib/openadaptor-depends.jar"
        subprocess.call(['java', '-cp', classPath , 'org.openadaptor.spring.SpringAdaptor', '-config', openAdaptorFile], stdout=outfd, stderr=errfd)
        outfd.close()
        errfd.close()
        #use this generateresponse if you want to see what is in the openadaptor configuration file
        #response = generateResponse("XML", data, respTemp)
        response = generate_responseXML(str(xml))
        #os.remove(auxPath + 'archivo_out')
        #os.remove(auxPath + 'archivo_err')
        xmldoc.unlink()
        #os.remove(path)        
        return str(xml), response, params
    else:
        #in case that the channel or category isn't found we will generate an empty file
        params = copy.deepcopy(posData)
        doc = Document()
        path = str(direccion) + "/agregator_files/temp/" + channel + "_" + category + ".xml"
        fich = open(path,'w')
        fich.write(doc.toxml())
        fich.close()
        data = {}
        xmldoc.unlink()
        xml = None
        response = "error category or channel not found"
        params = None
        return xml, response, params
#This will generate the url for the petition to the external server using the given parameters and tha template url parsed from the xml
def generate_URL(finalURL, listURL, allParams):
    j = 1
    fromx = 10
    toy = 30 
    if ('fromx' in allParams):
        fromx = allParams['fromx']
    if ('toy' in allParams):
        toy = allParams['toy']       
    while (j < len(listURL)):
        if (listURL[j] == 'minLong'):
            if ("longitude" in allParams):
                finalURL = finalURL + str(float(allParams['longitude']) - (float(allParams['radius'])/( 69 * 1.609344 )))
            else:     
                return "error longitude"
        else: 
            if (listURL[j] == 'minLat'):
                    if ("latitude" in allParams):
                        finalURL = finalURL + str(float(allParams['latitude']) - (float(allParams['radius'])/( 69 * 1.609344 )))
                    else:     
                        return "error latitude"
            else: 
                if (listURL[j] == 'maxLat'):
                        if ("latitude" in allParams):
                            finalURL = finalURL + str(float(allParams['latitude']) + (float(allParams['radius'])/( 69 * 1.609344 )))
                        else:     
                            return "error latitude" 
                else: 
                    if (listURL[j] == 'maxLong'):
                            if ("longitude" in allParams):
                                finalURL = finalURL + str(float(allParams['longitude']) + (float(allParams['radius'])/( 69 * 1.609344 )))
                            else:     
                                return "error longitude" 
                    else:
                        if (listURL[j] == 'fromx'):
                                    finalURL = finalURL + str(fromx)
                        else:
                            if (listURL[j] == 'toy'):
                                    finalURL = finalURL + str(toy)
                            else: 
                                if (listURL[j] in allParams):
                                    finalURL = finalURL + str(allParams[listURL[j]]) 
                                else: 
                                    if (listURL[j] in allParams):
                                        finalURL = finalURL + str(allParams[listURL[j]]) 
                                    else: 
                                        if (j % 2 == 0):
                                            finalURL = finalURL + listURL[j]  
                                        else:
                                            return "error " + listURL[j]
        j = j + 1
    return finalURL
#this function will get from the openadaptor xml configuration file the url of the petition. This is basically for testing actions
def decode_XML_template(XMLPath):
    xmldocument = minidom.parse(XMLPath)
    list = xmldocument.getElementsByTagName("bean")
    i = 0
    enc = False
    while (enc == False):
        if (str(list[i].attributes["id"].value) == "HttpReader"):
            propNode = list[i].getElementsByTagName('property')
            theURL = str(propNode[0].attributes["value"].value)
            enc = True
        i = i + 1   
    xmldocument.unlink()    
    return theURL        
#to get the path to this file
def getPath():
    direccion2 = path.dirname(path.abspath(__file__))
    return direccion2
#this will generate a HttpResponse
def generate_responseXML (xml):
    xmldoc = minidom.parse(xml)
    mime_type = "text/xml"
    return HttpResponse(xmldoc.toxml(), mime_type)
